package libRender;

import engine.render.type.Tri;
import engine.res.Bitmap;
import engine.res.Color;
import math.vector.vec2f;
import math.vector.vec3f;

public class Quad 
{
    
    private static Quad singleton;
    
    public static Quad gen() 
    {
        if (singleton == null) 
        {
            singleton = new Quad();
        }
        return singleton;
    }
    
    private Quad() 
    {
    }
    
    public Tri[] get(
            float x0, float y0, float z0, float s0, float t0, 
            float x1, float y1, float z1, float s1, float t1, 
            float x2, float y2, float z2, float s2, float t2, 
            float x3, float y3, float z3, float s3, float t3, 
            float nx, float ny, float nz, 
            Color modifier, Bitmap tex)
    {
        Tri tri0 = new Tri(
            x0, y0, z0, s0, t0,
            x1, y1, z1, s1, t1, 
            x2, y2, z2, s2, t2
        );
        tri0.colorModifier(modifier);
        tri0.texture(tex);
        tri0.normal(nx, ny, nz);
        
        Tri tri1 = new Tri(
            x0, y0, z0, s0, t0,
            x2, y2, z2, s2, t2, 
            x3, y3, z3, s3, t3
        );
        tri1.colorModifier(modifier);
        tri1.texture(tex);
        tri1.normal(nx, ny, nz);
        
        return new Tri[] { tri0, tri1 };
    }
    
    public Tri[] get(
            vec3f v0, float s0, float t0, 
            vec3f v1, float s1, float t1, 
            vec3f v2, float s2, float t2, 
            vec3f v3, float s3, float t3, 
            float nx, float ny, float nz, 
            Color modifier, Bitmap tex)
    {
        return get(
            v0.x, v0.y, v0.z, s0, t0, 
            v1.x, v1.y, v1.z, s1, t1, 
            v2.x, v2.y, v2.z, s2, t2, 
            v3.x, v3.y, v3.z, s3, t3, 
            nx, ny, nz, 
            modifier, tex
        );
    }
    
    public Tri[] get(
            vec3f v0, float s0, float t0, 
            vec3f v1, float s1, float t1, 
            vec3f v2, float s2, float t2, 
            vec3f v3, float s3, float t3, 
            vec3f normal, 
            Color modifier, Bitmap tex)
    {
        return get(
            v0.x, v0.y, v0.z, s0, t0, 
            v1.x, v1.y, v1.z, s1, t1, 
            v2.x, v2.y, v2.z, s2, t2, 
            v3.x, v3.y, v3.z, s3, t3, 
            normal.x, normal.y, normal.z, 
            modifier, tex
        );
    }
    
    public Tri[] get(
            vec3f v0, vec2f tx0, 
            vec3f v1, vec2f tx1, 
            vec3f v2, vec2f tx2, 
            vec3f v3, vec2f tx3, 
            vec3f normal, 
            Color modifier, Bitmap tex)
    {
        return get(
            v0.x, v0.y, v0.z, tx0.x, tx0.y, 
            v1.x, v1.y, v1.z, tx1.x, tx1.y, 
            v2.x, v2.y, v2.z, tx2.x, tx2.y, 
            v3.x, v3.y, v3.z, tx3.x, tx3.y, 
            normal.x, normal.y, normal.z, 
            modifier, tex
        );
    }
    
    public Tri[] get(
            vec3f[] verts, vec2f[] texCoords, 
            vec3f normal, 
            Color modifier, Bitmap tex)
    {
        return get(
            verts[0].x, verts[0].y, verts[0].z, texCoords[0].x, texCoords[0].y, 
            verts[1].x, verts[1].y, verts[1].z, texCoords[1].x, texCoords[1].y, 
            verts[2].x, verts[2].y, verts[2].z, texCoords[2].x, texCoords[2].y, 
            verts[3].x, verts[3].y, verts[3].z, texCoords[3].x, texCoords[3].y, 
            normal.x, normal.y, normal.z, 
            modifier, tex
        );
    }
    
    public Tri[] getGenericXY(
            float xpos, float ypos, float zpos, 
            float xsize, float ysize, 
            boolean positiveNorm, 
            Color modifier, Bitmap tex)
    {
        float xrad = xsize * 0.5f;
        float yrad = ysize * 0.5f;
        float xl = xpos - xrad;
        float xr = xpos + xrad;
        float yl = ypos - yrad;
        float yr = ypos + yrad;
        return positiveNorm
            ?
                get(
                    xr, yl, zpos, 1, 0, 
                    xr, yr, zpos, 1, 1, 
                    xl, yr, zpos, 0, 1, 
                    xl, yl, zpos, 0, 0, 
                    0, 0, 1, 
                    modifier, tex
                )
            :
                get(
                    xl, yl, zpos, 1, 0, 
                    xl, yr, zpos, 1, 1, 
                    xr, yr, zpos, 0, 1, 
                    xr, yl, zpos, 0, 0, 
                    0, 0, -1, 
                    modifier, tex
                )
        ;
    }
    
    public Tri[] getGenericXZ(
            float xpos, float ypos, float zpos, 
            float xsize, float zsize, 
            boolean positiveNorm, 
            Color modifier, Bitmap tex)
    {
        float xrad = xsize * 0.5f;
        float zrad = zsize * 0.5f;
        float xl = xpos - xrad;
        float xr = xpos + xrad;
        float zl = zpos - zrad;
        float zr = zpos + zrad;
        return positiveNorm
            ?
                get(
                    xl, ypos, zl, 1, 0, 
                    xl, ypos, zr, 1, 1, 
                    xr, ypos, zr, 0, 1, 
                    xr, ypos, zl, 0, 0, 
                    0, 1, 0, 
                    modifier, tex
                )
            :
                get(
                    xl, ypos, zr, 1, 0, 
                    xl, ypos, zl, 1, 1, 
                    xr, ypos, zl, 0, 1, 
                    xr, ypos, zr, 0, 0, 
                    0, -1, 0, 
                    modifier, tex
                )
        ;
    }
    
    public Tri[] getGenericYZ(
            float xpos, float ypos, float zpos, 
            float ysize, float zsize, 
            boolean positiveNorm, 
            Color modifier, Bitmap tex)
    {
        float yrad = ysize * 0.5f;
        float zrad = zsize * 0.5f;
        float yl = ypos - yrad;
        float yr = ypos + yrad;
        float zl = zpos - zrad;
        float zr = zpos + zrad;
        return positiveNorm 
            ? 
                get(
                    xpos, yr, zl, 1, 1, 
                    xpos, yr, zr, 0, 1, 
                    xpos, yl, zr, 0, 0, 
                    xpos, yl, zl, 1, 0, 
                    1, 0, 0, 
                    modifier, tex
                )
            : 
                get(
                    xpos, yr, zr, 1, 1, 
                    xpos, yr, zl, 0, 1, 
                    xpos, yl, zl, 0, 0, 
                    xpos, yl, zr, 1, 0, 
                    -1, 0, 0, 
                    modifier, tex
                )
        ;
    }
    
}
